#include <windows.h>
#include <stdio.h>
#include <tlhelp32.h>
#include <stdlib.h>

#define SYSTEM_COFIG_NAME "LoginRecorderInstallDir"
#define RECORDER_NAME "LoginRecorder.exe"
#define CMD_LENGTH 200
#define SLEEP_TIME 5000
#define LOG_FILE "D:\\loginRecorderLog.txt"
#define RECORDER_NAME "LoginRecorder.exe"
#define SERVICE_NAME "HWTimeRecorder"


SERVICE_STATUS ServiceStatus;
SERVICE_STATUS_HANDLE ServiceStatusHandle;

int startLoginRecorderIfDontExist() {
	char processName[] = RECORDER_NAME;
	char startCmd[CMD_LENGTH];
	memset(startCmd, '\0', CMD_LENGTH);
	sprintf(startCmd, "start %s\\%s", getenv(SYSTEM_COFIG_NAME), RECORDER_NAME);
    HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hSnapShot != INVALID_HANDLE_VALUE) {
        PROCESSENTRY32 pe32;
        pe32.dwSize = sizeof(pe32);
        if (Process32First(hSnapShot, &pe32)) {
            do {
                if (strcmp(pe32.szExeFile, processName) == 0) {
                    CloseHandle(hSnapShot);
                    return 0;
                }
            } while (Process32Next(hSnapShot, &pe32));
        }
    }
    CloseHandle(hSnapShot);
    system(startCmd);
    return 0;
}

int WriteToLog(char* str) {
    FILE* log;
    log = fopen(LOG_FILE, "a+");
    if (log == NULL)
        return -1;
    fprintf(log, "%s\n", str);
    fclose(log);
    return 0;
}

int InitService() {
    int result;
    result = WriteToLog("loginRecorderService started.");
    return(result);
}

void ServiceControlHandler(DWORD request) {
    switch (request) {
    case SERVICE_CONTROL_STOP:
    case SERVICE_CONTROL_SHUTDOWN:
        WriteToLog("loginRecorderService stopped.");
        ServiceStatus.dwWin32ExitCode = 0;
        ServiceStatus.dwCurrentState = SERVICE_STOPPED;
        break;
    default:
        break;
    }

    SetServiceStatus(ServiceStatusHandle, &ServiceStatus);

    return;
}

void ServiceMain(int argc, char** argv) {
    ServiceStatus.dwServiceType = SERVICE_WIN32;
    ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
    ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
    ServiceStatus.dwWin32ExitCode = 0;
    ServiceStatus.dwServiceSpecificExitCode = 0;
    ServiceStatus.dwCheckPoint = 0;
    ServiceStatus.dwWaitHint = 0;

    ServiceStatusHandle = RegisterServiceCtrlHandler(
        (LPCSTR)SERVICE_NAME,
        (LPHANDLER_FUNCTION)ServiceControlHandler
    );
    if (ServiceStatusHandle == NULL) {
        return;
    }
    int error = InitService();
    if (error) {
        ServiceStatus.dwCurrentState = SERVICE_STOPPED;
        ServiceStatus.dwWin32ExitCode = -1;
        SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
        return;
    }
    ServiceStatus.dwCurrentState = SERVICE_RUNNING;
    SetServiceStatus(ServiceStatusHandle, &ServiceStatus);

    MEMORYSTATUS memory;
    while (ServiceStatus.dwCurrentState == SERVICE_RUNNING) {
        char buffer[16];
        GlobalMemoryStatus(&memory);
        sprintf(buffer, "%d", memory.dwAvailPhys);
        int result = WriteToLog(buffer);
        if (result) {
            ServiceStatus.dwCurrentState = SERVICE_STOPPED;
            ServiceStatus.dwWin32ExitCode = -1;
            SetServiceStatus(ServiceStatusHandle, &ServiceStatus);
            return;
        }
		WriteToLog("Service monitor the recorder");
		startLoginRecorderIfDontExist();
        Sleep(SLEEP_TIME);
    }
    return;
}

int main(int argc, char** argv) {
    SERVICE_TABLE_ENTRY entry[2] = {
		{SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION)ServiceMain},
		{NULL, NULL}
	};
    StartServiceCtrlDispatcher(entry);
    return 0;
}


